import java.util.Scanner;

/**
 * Created by L.jp
 * Description:问题描述：在计算机中，通配符一种特殊语法，广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
 * 要求：
 * 实现如下2个通配符：
 * *：匹配0个或以上的字符（注：能被*和?匹配的字符仅由英文字母和数字0到9组成，下同）
 * ？：匹配1个字符
 *
 * 注意：匹配时不区分大小写。
 *
 * 输入：
 * 通配符表达式；
 * 一组字符串。
 * 输出：
 *
 * 返回不区分大小写的匹配结果，匹配成功输出true，匹配失败输出false
 * User: 86189
 * Date: 2022-03-12
 * Time: 15:22
 */
public class Main {
    //此题有两种解法，一个是递归版本，递归版本容易超时，所以我们使用动态规划版本
    //像这种关于两个字符串联系的问题可以使用动态规划来求解
    //使用一个布尔数组来存储两个字符串的对应位置是否匹配，最后只需要求得数组的最后一个位置是否为真就可以
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            //通配符串
            String pattern = in.nextLine();
            pattern = pattern.toLowerCase();
            //字符串
            String string = in.nextLine();
            string = string.toLowerCase();
            //打印结果
            System.out.println(isMatch(pattern, string));
        }
    }
    //力扣版
   /* public static boolean isMatch(String p, String s) {
        //首先规定好数组的长度，我们二维数组的长和宽需要比字符串的长度多1，因为我们需要借助一个空串来作为初始值
        int pl=p.length();
        int sl=s.length();
        //定义一个布尔类型的数组存储pattern的前i个字符串和string的前j个字符串是否匹配的真值
        boolean[][] dp=new boolean[sl+1][pl+1];
        //接着构造数组
        //初始化数组，表示空串和空串能匹配
        dp[0][0]=true;
        //第一行dp[0][j],s为空,与p匹配,所以只要p开始为*才为true
        for(int j = 1;j<=pl; j++){
            //因为我们的空格字符占了一个位置，所以对与字符串本身来说字符串的下标都要在数组的下标-1
            if(p.charAt(j-1)=='*'){
                dp[0][j]=dp[0][j-1];
            }else{
                break;
            }
        }
        //从数组第二行第二列开始构造
        for(int i = 1; i <= sl; i++){
            for(int j=1;j<=pl; j++){
                //接下来判断三种情况  这些情况的状态定义方程我们可以通过自己模拟+表格规律来转换公式
                //当模式串有 ？   时
                if(p.charAt(j-1)=='?' || p.charAt(j-1)==s.charAt(i-1)){
                    //如果模式串有问号或者当前字符相等，那么就只需要看前面的字符串是否匹配即可
                    dp[i][j] = dp[i-1][j-1];
                }else if(p.charAt(j-1)=='*'){
                    //如果模式串是  *  h号，那么表示他可以匹配字符串前面的所有字符，只需要看前面的匹配结果是否为真即可
                    dp[i][j] = dp[i][j-1] || dp[i-1][j];
                }
                //其余情况都是初始值false

            }
        }
        return dp[sl][pl];
    }*/
    
    //牛客版本
    //dp数组的值可以通过自己模拟字符串匹配+判断，和画二维数组来推出状态方程
    public static boolean isMatch(String p, String s) {
        char[] pp = p.toCharArray();
        char[] ss = s.toCharArray();
        int ppl = pp.length;
        int ssl = ss.length;
        boolean[][] dp = new boolean[ssl + 1][ppl + 1];
        //状态初始化
        dp[0][0] = true;
        for (int i = 0; i <= ssl; i++) {
            //数组第一列也即j==0时真值就是假，就是说空串没法和任何字符串匹配
            for (int j = 1; j <= ppl; j++) {
                //接下来构造二维数组
                //分为两组情况，一个是通配串有 *  号
                //j-1指的是字符串的索引，j时dp数组的索引
                if (pp[j - 1] == '*') {
                    //对于第一行来说
                    if (i == 0) {
                        dp[i][j] = dp[i][j - 1];
                    } else {
                        //对于其他的行，如果模式串有 *  号，那么就是根据二维数组的状态定义方程得出dp[i][j]=dp[i-1][j] || dp[i][j-1]
                        //当然这个时候字符串需要判断是不是数字 ‘.' 或者字母
                        if (ss[i-1] == '.' || (ss[i-1] >= 'a' && ss[i-1] <= 'z') || (ss[i-1] >= 'A' && ss[i-1] <= 'Z')
                                || (ss[i-1] >= '0' && ss[i-1] <= '9')) {
                            dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; //这个就是* 号可以匹配 0个或者一个 多个的转化
                        }
                    }
                } else {
                    //接下来这里的情况就是模式串有问号 ，‘.'  或者其他的字符
                    //我们依旧从数组第二行开始判断
                    //这就是要判断模式串和字符串的字符的前一个字符是否相等即可
                    if (i > 0 && isSame(ss[i - 1], pp[j - 1])) {
                        //如果相等，那么当前的状态就取决于前一个的状态
                        dp[i][j] = dp[i - 1][j - 1];
                    }
        
                }
            }
        }
        return  dp[ssl][ppl];
    }
    //判断两个字符是否相等
    public static boolean isSame(char s,char t) {
       //情况一：模式串有问号
        if(t=='?') {
            //如果模式串等于问号，那么就可以一定可以匹配成功
            return true;
        }
        //模式串或者字符串有小写，那么我们要转换成大写判断
        if(t>='a' && t<='z') {
            t=(char) (t-'a'+'A');
        }
        if(s>='a' && s<='z') {
            s=(char) (s-'a'+'A');
        }
        return s==t; //看他们是否相等
    }
}

